package com.lswms.modules.lswms.service.impl.orders;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import com.lswms.common.utils.Result;
import com.lswms.modules.lswms.service.impl.uniquecode.UniquecodeServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lswms.common.page.PageData;
import com.lswms.common.service.impl.CrudServiceImpl;
import com.lswms.modules.lswms.MEGConstant;
import com.lswms.modules.lswms.Constant.LocationConstant;
import com.lswms.modules.lswms.Constant.OrderConstant;
import com.lswms.modules.lswms.Constant.TaskConstant;
import com.lswms.modules.lswms.Constant.TradeConstant;
import com.lswms.modules.lswms.controller.orders.OrdersController;
import com.lswms.modules.lswms.dao.base.AllocationstrategydetailDao;
import com.lswms.modules.lswms.dao.base.LocationDao;
import com.lswms.modules.lswms.dao.base.SkuDao;
import com.lswms.modules.lswms.dao.orders.OrderallocationDao;
import com.lswms.modules.lswms.dao.orders.OrderdetailDao;
import com.lswms.modules.lswms.dao.orders.OrderdetaillistDao;
import com.lswms.modules.lswms.dao.orders.OrdersDao;
import com.lswms.modules.lswms.dao.stock.InventoryDao;
import com.lswms.modules.lswms.dao.stock.LotDao;
import com.lswms.modules.lswms.dao.stock.TradeDao;
import com.lswms.modules.lswms.dao.task.TaskDao;
import com.lswms.modules.lswms.dao.uniquecode.UniquecodeDao;
import com.lswms.modules.lswms.dao.uniquecode.UniquecoderecordDao;
import com.lswms.modules.lswms.dto.orders.OrderdetailDTO;
import com.lswms.modules.lswms.entity.base.AllocationstrategydetailEntity;
import com.lswms.modules.lswms.entity.base.LocationEntity;
import com.lswms.modules.lswms.entity.base.SkuEntity;
import com.lswms.modules.lswms.entity.orders.OrderdetailEntity;
import com.lswms.modules.lswms.entity.orders.OrderdetaillistEntity;
import com.lswms.modules.lswms.entity.orders.OrdersEntity;
import com.lswms.modules.lswms.entity.stock.InventoryEntity;
import com.lswms.modules.lswms.entity.stock.LotEntity;
import com.lswms.modules.lswms.entity.stock.TradeEntity;
import com.lswms.modules.lswms.entity.task.TaskEntity;
import com.lswms.modules.lswms.entity.uniquecode.UniquecodeEntity;
import com.lswms.modules.lswms.entity.uniquecode.UniquecoderecordEntity;
import com.lswms.modules.lswms.service.base.SequenceService;
import com.lswms.modules.lswms.service.orders.OrderallocationService;
import com.lswms.modules.lswms.service.orders.OrderdetailService;
import com.lswms.modules.lswms.service.orders.OrderdetaillistService;

/**
 * 出库明细
 *
 * @author DX sunlightcs@gmail.com
 * @since 1.0.0 2021-06-24
 */
@Service
public class OrderdetailServiceImpl extends CrudServiceImpl<OrderdetailDao, OrderdetailEntity, OrderdetailDTO>
		implements OrderdetailService {

	@Autowired
	OrderdetaillistDao orderdetaillistDao;

	@Autowired
	InventoryDao inventoryDao;

	@Autowired
	LotDao lotDao;

	@Autowired
	SequenceService sequenceService;

	@Autowired
	TradeDao tradeDao;

	@Autowired
	OrdersDao ordersDao;

	@Autowired
	SkuDao skuDao;

	@Autowired
	TaskDao taskDao;

	@Autowired
	LocationDao locationDao;

	@Autowired
	OrderdetaillistService orderdetaillistService;

	@Autowired
	AllocationstrategydetailDao allocationstrategydetailDao;

	@Autowired
	OrderallocationService orderallocationService;

	@Autowired
	OrderallocationDao orderallocationDao;
	
	@Autowired
	private UniquecodeDao uniquecodeDao ;
	
	@Autowired
	private UniquecoderecordDao uniquecoderecordDao;
	
	@Autowired
	private UniquecodeServiceImpl uniquecodeService;

	@Override
	public QueryWrapper<OrderdetailEntity> getWrapper(Map<String, Object> params) {
		String id = (String) params.get("id");
		String orderkey = (String) params.get("orderkey");
		String line = (String) params.get("line");
		String sku = (String) params.get("sku");
		String descr = (String) params.get("descr");
		String status = (String) params.get("status");

		QueryWrapper<OrderdetailEntity> wrapper = new QueryWrapper<>();
		wrapper.eq(StringUtils.isNotBlank(id), "lswms_orderdetail.id", id);
		wrapper.eq(StringUtils.isNotBlank(orderkey), "lswms_orderdetail.orderkey", orderkey);
		wrapper.eq(StringUtils.isNotBlank(line), "lswms_orderdetail.line", line);
		wrapper.eq(StringUtils.isNotBlank(sku), "lswms_orderdetail.sku", sku);
		wrapper.like(StringUtils.isNotBlank(descr), "lswms_sku.descr", descr);
		wrapper.eq(StringUtils.isNotBlank(status), "lswms_orderdetail.status", status);

		wrapper.orderByDesc("lswms_orderdetail.orderkey");
		wrapper.orderByAsc("lswms_orderdetail.line");

		return wrapper;
	}

	@Override
	public PageData<OrderdetailEntity> pageBySql(Map<String, Object> params) {
		IPage<OrderdetailEntity> page = baseDao.selectPageBySql(getPage(params, null, false), getWrapper(params));
		return getPageData(page, OrderdetailEntity.class);
	}

	@Override
	public Integer getOrderdetailLine(String orderkey) {
		Integer count = 0;
		if (StringUtils.isNotBlank(orderkey)) {
			QueryWrapper<OrderdetailEntity> queryWrapper = new QueryWrapper<OrderdetailEntity>();
			queryWrapper.eq("orderkey", orderkey);
			queryWrapper.select(" isnull( max(line),0) maxline ");

			List<Map<String, Object>> getlist = baseDao.selectMaps(queryWrapper);
			if (getlist.size() > 0) {
				Map<String, Object> map = getlist.get(0);
				Object obj = map.get("maxline");
				if (obj instanceof Integer) {
					count = (Integer) obj;
				} else if (obj instanceof String) {
					count = Integer.valueOf((String) map.get("maxline"));
				}
			}
		}

		return count;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String allocation(List<OrderdetailEntity> orderList) {
		try {
			// 如果当前存在增在分配的订单，则不允许分配
			Integer countCurrnet = orderallocationDao.selectCount(null);
			if (countCurrnet > 0) {
				return MEGConstant.ORDER_HAS_OTHER_ALLOCATION;
			}

			// 分配控制，有出库但正在分配时，不允许再有其他相关的操作,独立事务
			orderallocationService.addOrderList(orderList);

			for (OrderdetailEntity orderdetailEntity : orderList) {

				String msg = allocation(orderdetailEntity);

				if (msg != null) {

					// 回滚事务
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return msg;

				}
			}
		} catch (Exception e) {
			throw e;
		} finally {
			orderallocationService.delete(orderList);
		}
		return null;
	}

	private String allocation(OrderdetailEntity orderdetailEntity) {
		// 查找订单详细信息
		QueryWrapper<OrderdetailEntity> orderdetailQuery = new QueryWrapper<OrderdetailEntity>();
		orderdetailQuery.eq("orderkey", orderdetailEntity.getOrderkey());
		orderdetailQuery.eq("line", orderdetailEntity.getLine());
		orderdetailQuery.ne("status", OrderConstant.ORDERSTATUS_25);
		OrderdetailEntity orderdetail = baseDao.selectOne(orderdetailQuery);
		if (orderdetail == null) {
			return null;
		}

		// 查询出库单出库策略
		QueryWrapper<AllocationstrategydetailEntity> allocationstrategydetailQuery = new QueryWrapper<AllocationstrategydetailEntity>();
		allocationstrategydetailQuery.eq("strategykey", orderdetail.getAllocationstrategy());
		List<AllocationstrategydetailEntity> list = allocationstrategydetailDao
				.selectList(allocationstrategydetailQuery);
		for (AllocationstrategydetailEntity allocationstrategydetailEntity : list) {
			// 根据分配策略，获取可以分配的库存
			List<InventoryEntity> availableStockList = getInventoryByStrategy(orderdetail,
					allocationstrategydetailEntity);

			// 添加拣货明细
			String msg = addOrderdetailListByAvailableStock(orderdetail, availableStockList);

		}

//		for (OrderdetaillistEntity orderdetaillistEntity : orderdetails) {
//			String msg = delivery(orderdetaillistEntity);
//			if (msg != null) {
//				// 回滚事务
//				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//				return msg;
//			}
//		}
		orderdetaillistService.changeOrderStatus(orderdetailEntity.getOrderkey());
		return null;
	}

	private String addOrderdetailListByAvailableStock(OrderdetailEntity orderdetail,
			List<InventoryEntity> availableStockList) {
		for (InventoryEntity availableStock : availableStockList) {
			BigDecimal diffqtyOrder = orderdetail.getDiffqty();
			BigDecimal allocateqtyOrder = orderdetail.getAllocateqty();
			BigDecimal pickqtyOrder = orderdetail.getPickqty();
			// 需要分配的量
			BigDecimal qtyNeed = diffqtyOrder.subtract(allocateqtyOrder).subtract(pickqtyOrder);
			if (qtyNeed.compareTo(new BigDecimal(0)) > 0) {
				String msg = addOrderdetailListByAvailableStock(orderdetail, availableStock);
				if (msg != null) {
					return msg;
				}
			}

		}
		return null;
	}

	private String addOrderdetailListByAvailableStock(OrderdetailEntity orderdetail, InventoryEntity availableStock) {

		BigDecimal diffqtyOrder = orderdetail.getDiffqty();
		BigDecimal allocateqtyOrder = orderdetail.getAllocateqty();
		BigDecimal pickqtyOrder = orderdetail.getPickqty();

		BigDecimal qtyInventory = availableStock.getQty();
		BigDecimal pickqtyInventory = availableStock.getPickqty();

		// 需要分配的量
		BigDecimal qtyNeed = diffqtyOrder.subtract(allocateqtyOrder).subtract(pickqtyOrder);
		// 库存剩余量
		BigDecimal qtySurplus = qtyInventory.subtract(pickqtyInventory);

		BigDecimal zero = new BigDecimal(0);
		// 最终可用的分配量
		BigDecimal qty = zero;
		if (qtyNeed.compareTo(zero) > 0 && qtySurplus.compareTo(zero) > 0) {
			if (qtyNeed.compareTo(qtySurplus) > 0) {
				qty = qtySurplus;
			} else {
				qty = qtyNeed;
			}
		} else {
			return null;
		}

		// 增加拣货记录
		int lineList = orderdetaillistDao.getNextOrderdetaillistLinelist(orderdetail.getOrderkey(),
				orderdetail.getLine());
		OrderdetaillistEntity orderdetaillistEntity = new OrderdetaillistEntity();
		orderdetaillistEntity.setOrderkey(orderdetail.getOrderkey());
		orderdetaillistEntity.setLine(orderdetail.getLine());
		orderdetaillistEntity.setLinelist(lineList);
		orderdetaillistEntity.setSku(orderdetail.getSku());
		orderdetaillistEntity.setUnit(orderdetail.getUnit());
		orderdetaillistEntity.setPack(orderdetail.getPack());
		orderdetaillistEntity.setStatus(OrderConstant.ORDERSTATUS_5);
		orderdetaillistEntity.setQty(qty);
		orderdetaillistEntity.setActqty(qty);
		orderdetaillistEntity.setFromloc(availableStock.getLocation());
		orderdetaillistEntity.setFromtray(availableStock.getTray());
		orderdetaillistEntity.setFrombox(availableStock.getBox());
		orderdetaillistEntity.setLoc(availableStock.getLocation());
		orderdetaillistEntity.setTray(availableStock.getTray());
		orderdetaillistEntity.setBox(availableStock.getBox());
		orderdetaillistEntity.setToloc(OrderConstant.ORDER_PICK_LOCATION);
		orderdetaillistEntity.setTotray(availableStock.getTray());
		orderdetaillistEntity.setTobox(availableStock.getBox());
		orderdetaillistEntity.setLot(availableStock.getLot());
		orderdetaillistDao.insert(orderdetaillistEntity);

		// 变更库存记录
		UpdateWrapper<InventoryEntity> inventoryUpdate = new UpdateWrapper<InventoryEntity>();
		inventoryUpdate.eq("sku", availableStock.getSku());
		inventoryUpdate.eq("location", availableStock.getLocation());
		inventoryUpdate.eq("lot", availableStock.getLot());
		inventoryUpdate.eq("tray", availableStock.getTray());
		inventoryUpdate.eq("box", availableStock.getBox());
		inventoryUpdate.set("pickqty", pickqtyInventory.add(qty));
		inventoryDao.update(null, inventoryUpdate);

		// 变更拣货明细的信息
		UpdateWrapper<OrderdetailEntity> orderdetailUpdate = new UpdateWrapper<OrderdetailEntity>();
		orderdetailUpdate.eq("orderkey", orderdetail.getOrderkey());
		orderdetailUpdate.eq("line", orderdetail.getLine());
		orderdetailUpdate.eq("sku", orderdetail.getSku());
		orderdetailUpdate.set("allocateqty", allocateqtyOrder.add(qty));
		update(null, orderdetailUpdate);

		orderdetail.setAllocateqty(allocateqtyOrder.add(qty));
		return null;
	}

	private List<InventoryEntity> getInventoryByStrategy(OrderdetailEntity orderdetailEntity,
			AllocationstrategydetailEntity allocationstrategydetailEntity) {
		// 查询物料信息
		QueryWrapper<SkuEntity> skuEntityQuery = new QueryWrapper<SkuEntity>();
		skuEntityQuery.eq("sku", orderdetailEntity.getSku());
		SkuEntity skuEntity = skuDao.selectOne(skuEntityQuery);
		if (skuEntity == null) {
			return null;
		}

		// 查询库存记录
		QueryWrapper<InventoryEntity> inventoryQuery = new QueryWrapper<InventoryEntity>();
		inventoryQuery.eq("a.sku", orderdetailEntity.getSku());

		// 指定属性出库
		inventoryQuery.eq(orderdetailEntity.getLot1() != null, "b.lot1", orderdetailEntity.getLot1());
		inventoryQuery.eq(orderdetailEntity.getLot2() != null, "b.lot2", orderdetailEntity.getLot2());
		inventoryQuery.eq(StringUtils.isNotBlank(orderdetailEntity.getLot3()), "b.lot3", orderdetailEntity.getLot3());
		inventoryQuery.eq(StringUtils.isNotBlank(orderdetailEntity.getLot4()), "b.lot4", orderdetailEntity.getLot4());
		inventoryQuery.eq(StringUtils.isNotBlank(orderdetailEntity.getLot5()), "b.lot5", orderdetailEntity.getLot5());
		inventoryQuery.eq(StringUtils.isNotBlank(orderdetailEntity.getLot6()), "b.lot6", orderdetailEntity.getLot6());
		inventoryQuery.eq(StringUtils.isNotBlank(orderdetailEntity.getLot7()), "b.lot7", orderdetailEntity.getLot7());
		inventoryQuery.eq(StringUtils.isNotBlank(orderdetailEntity.getLot8()), "b.lot8", orderdetailEntity.getLot8());
		inventoryQuery.eq(StringUtils.isNotBlank(orderdetailEntity.getLot9()), "b.lot9", orderdetailEntity.getLot9());
		inventoryQuery.eq(StringUtils.isNotBlank(orderdetailEntity.getLot10()), "b.lot10",
				orderdetailEntity.getLot10());
		inventoryQuery.eq(StringUtils.isNotBlank(orderdetailEntity.getLot11()), "b.lot11",
				orderdetailEntity.getLot11());
		inventoryQuery.eq(StringUtils.isNotBlank(orderdetailEntity.getLot12()), "b.lot12",
				orderdetailEntity.getLot12());
		inventoryQuery.eq(StringUtils.isNotBlank(orderdetailEntity.getLot13()), "b.lot13",
				orderdetailEntity.getLot13());
		inventoryQuery.eq(StringUtils.isNotBlank(orderdetailEntity.getLot14()), "b.lot14",
				orderdetailEntity.getLot14());
		inventoryQuery.eq(StringUtils.isNotBlank(orderdetailEntity.getLot15()), "b.lot15",
				orderdetailEntity.getLot15());

		inventoryQuery.eq("c.loc_status", LocationConstant.LOC_STATUS_OK);
		inventoryQuery.eq(StringUtils.isNotBlank(allocationstrategydetailEntity.getLocationtype()), "c.loc_type",
				allocationstrategydetailEntity.getLocationtype());
		inventoryQuery.eq(StringUtils.isNotBlank(allocationstrategydetailEntity.getLocationcategory()),
				"c.loc_category", allocationstrategydetailEntity.getLocationcategory());
		inventoryQuery.eq(StringUtils.isNotBlank(allocationstrategydetailEntity.getAllocationzone()), "c.zonecode",
				allocationstrategydetailEntity.getLocationcategory());

		inventoryQuery.ne("c.zonecode", "TEMPA");

		inventoryQuery.notExists(
				" select 1 from lswms_task where lswms_task.status<9 and (a.tray = lswms_task.fromtray  or a.tray = lswms_task.totray ) ");
		inventoryQuery.notExists(
				"select  1 from WCS_DDJ where c.lane = WCS_DDJ.DVC_NO and WCS_DDJ.status <>'1' ");
		
		if (allocationstrategydetailEntity.getSort1().equalsIgnoreCase("rolatebylot")) {
			inventoryQuery.orderByAsc(skuEntity.getRolateby());
		} else if (allocationstrategydetailEntity.getSort1().equalsIgnoreCase("location")) {
			inventoryQuery.orderByAsc("a.location");
		}
		if (allocationstrategydetailEntity.getSort2().equalsIgnoreCase("rolatebylot")) {
			inventoryQuery.orderByAsc(skuEntity.getRolateby());
		} else if (allocationstrategydetailEntity.getSort2().equalsIgnoreCase("location")) {
			inventoryQuery.orderByAsc("a.location");
		}
		if (allocationstrategydetailEntity.getSort3().equalsIgnoreCase("rolatebylot")) {
			inventoryQuery.orderByAsc(skuEntity.getRolateby());
		} else if (allocationstrategydetailEntity.getSort3().equalsIgnoreCase("location")) {
			inventoryQuery.orderByAsc("a.location");
		}
		if (allocationstrategydetailEntity.getSort4().equalsIgnoreCase("rolatebylot")) {
			inventoryQuery.orderByAsc(skuEntity.getRolateby());
		} else if (allocationstrategydetailEntity.getSort4().equalsIgnoreCase("location")) {
			inventoryQuery.orderByAsc("a.location");
		}

		List<InventoryEntity> list = inventoryDao.selectAllocation(inventoryQuery);

		return list;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String delivery(List<OrderdetailEntity> orderList) {

		for (OrderdetailEntity orderdetailEntity : orderList) {
			//System.out.println(orderdetailEntity);
			String msg = delivery(orderdetailEntity);

			if (msg != null) {
				// 回滚事务
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return msg;
			}
		}
		return null;
	}

	private String delivery(OrderdetailEntity orderdetailEntity) {
		// 立体库 或 需要管理唯一码的物料 必须分拣后才能发货
		QueryWrapper<OrderdetaillistEntity> orderdetaillistQueryCheck = new QueryWrapper<OrderdetaillistEntity>();
		orderdetaillistQueryCheck.eq("orderkey", orderdetailEntity.getOrderkey());
		orderdetaillistQueryCheck.eq("line", orderdetailEntity.getLine());
		orderdetaillistQueryCheck.lt("status", OrderConstant.ORDERSTATUS_13);
		orderdetaillistQueryCheck.and(wrapper -> wrapper.exists(
				" select 1 from lswms_location where lswms_orderdetaillist.fromloc = lswms_location.location and lswms_location.loc_category='STEREO' ")
				.or()
				.exists("  select 1 from lswms_sku where lswms_orderdetaillist.sku =  lswms_sku.sku and lswms_sku.isuniquecode='1'"));
		Integer countCheck = orderdetaillistDao.selectCount(orderdetaillistQueryCheck);
		if (countCheck > 0) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return "需要管理唯一码或从立体库出库的物料，必须分拣后才能发货";
		}

		// 查找与订单相关的所有拣货明细
		QueryWrapper<OrderdetaillistEntity> orderdetaillistQuery = new QueryWrapper<OrderdetaillistEntity>();
		orderdetaillistQuery.eq("orderkey", orderdetailEntity.getOrderkey());
		orderdetaillistQuery.eq("line", orderdetailEntity.getLine());
		orderdetaillistQuery.lt("status", OrderConstant.ORDERSTATUS_21);
		List<OrderdetaillistEntity> Orderdetaillists = orderdetaillistDao.selectList(orderdetaillistQuery);
		Result result = uniquecodeService.deliveryUniquecode(Orderdetaillists);
		if (result.getCode() != 0) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		}
		for (OrderdetaillistEntity orderdetaillistEntity : Orderdetaillists) {
			String msg = delivery(orderdetaillistEntity);
			if (msg != null) {
				// 回滚事务
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return msg;
			}
		}
		orderdetaillistService.changeOrderStatus(orderdetailEntity.getOrderkey());
		return null;
	}

	private String delivery(OrderdetaillistEntity orderdetaillistEntity) {
		// 获取库存量
		QueryWrapper<InventoryEntity> inventoryQuery = new QueryWrapper<InventoryEntity>();
		inventoryQuery.eq("sku", orderdetaillistEntity.getSku());
		inventoryQuery.eq("lot", orderdetaillistEntity.getLot());
		inventoryQuery.eq("location", orderdetaillistEntity.getLoc());
		inventoryQuery.eq("tray", orderdetaillistEntity.getTray());
		inventoryQuery.eq("box", orderdetaillistEntity.getBox());
		InventoryEntity inventoryEntity = inventoryDao.selectOne(inventoryQuery);
		// 校验数量
		BigDecimal orderActqty = orderdetaillistEntity.getActqty();
		BigDecimal inventoryQty = inventoryEntity ==null?new BigDecimal(0):inventoryEntity.getQty();
		BigDecimal inventoryPickQty = inventoryEntity ==null?new BigDecimal(0): inventoryEntity.getPickqty();
		if (orderActqty.compareTo(inventoryPickQty) > 0) {
			// 回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return MEGConstant.INVENTORY_PICKQTY_NOT_MATCH_ORDERS_ACTQTY;
		}
		if (inventoryPickQty.compareTo(inventoryQty) > 0) {
			// 回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return MEGConstant.INVENTORY_PICKQTY_NOT_MATCH_QTY;
		}

		//检查唯一码，如果有，则删除唯一码
		QueryWrapper<SkuEntity> skuQuery = new QueryWrapper<SkuEntity>();
		skuQuery.eq("sku", orderdetaillistEntity.getSku()) ;
		SkuEntity skuEntity = skuDao.selectOne(skuQuery);
		String isuniquecode = skuEntity.getIsuniquecode();
		if(StringUtils.isNoneBlank(isuniquecode) && isuniquecode.equals("1")){
			QueryWrapper<UniquecodeEntity> uniquecodeQuery = new QueryWrapper<UniquecodeEntity>(); 
			uniquecodeQuery.eq("lot", orderdetaillistEntity.getLot());
			uniquecodeQuery.eq("tray", orderdetaillistEntity.getTray());
			uniquecodeQuery.eq("box", orderdetaillistEntity.getBox());
			
			List<UniquecodeEntity> list = uniquecodeDao.selectList(uniquecodeQuery);
			if( orderActqty.compareTo(new BigDecimal(list.size()))!=0 ) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "箱："+orderdetaillistEntity.getTray() + "格："+ orderdetaillistEntity.getBox()+"的发货数量与唯一码数量不相同，不能发货";
			}
			
			for (UniquecodeEntity uniquecodeEntity : list) {
				//增加历史记录
				UniquecoderecordEntity uniquecoderecordEntity = new UniquecoderecordEntity();
				uniquecoderecordEntity.setUniquecode(uniquecodeEntity.getUniquecode().trim());
				uniquecoderecordEntity.setFromtray(uniquecodeEntity.getTray());
				uniquecoderecordEntity.setFrombox(uniquecodeEntity.getBox());	
				uniquecoderecordEntity.setTotray(StringUtils.EMPTY);
				uniquecoderecordEntity.setTobox(StringUtils.EMPTY);
				uniquecoderecordEntity.setSku(uniquecodeEntity.getSku());
				uniquecoderecordEntity.setLot(uniquecodeEntity.getLot());
				uniquecoderecordEntity.setSourcetype("PICK");
				uniquecoderecordEntity.setSourcetable("orderdetaillist");
				uniquecoderecordEntity.setSourceid(orderdetaillistEntity.getId());
				uniquecoderecordEntity.setSourcekey(orderdetaillistEntity.getOrderkey());
				uniquecoderecordEntity.setSourceline(orderdetaillistEntity.getLine());
				uniquecoderecordEntity.setSourcelinelist(orderdetaillistEntity.getLinelist()) ;
				uniquecoderecordDao.insert(uniquecoderecordEntity) ;
				
				UpdateWrapper<UniquecodeEntity> deleteWrapper = new UpdateWrapper<UniquecodeEntity>();
				deleteWrapper.eq("uniqueCode", uniquecodeEntity.getUniquecode()) ;
				deleteWrapper.eq("lot", orderdetaillistEntity.getLot());
				deleteWrapper.eq("tray", orderdetaillistEntity.getTray());
				deleteWrapper.eq("box", orderdetaillistEntity.getBox());
				uniquecodeDao.delete(deleteWrapper);;
			}
		}
		
		
		// 库存的更新数据
		if( inventoryEntity !=null) {
			InventoryEntity inventoryEntityUpdate = new InventoryEntity();
			inventoryEntityUpdate.setQty(inventoryQty.subtract(orderActqty));
			inventoryEntityUpdate.setPickqty(inventoryPickQty.subtract(orderActqty));
			UpdateWrapper<InventoryEntity> inventoryWrapperUpdate = new UpdateWrapper<InventoryEntity>();
			inventoryWrapperUpdate.eq("sku", inventoryEntity.getSku());
			inventoryWrapperUpdate.eq("lot", inventoryEntity.getLot());
			inventoryWrapperUpdate.eq("location", inventoryEntity.getLocation());
			inventoryWrapperUpdate.eq("tray", inventoryEntity.getTray());
			inventoryWrapperUpdate.eq("box", inventoryEntity.getBox());
			inventoryWrapperUpdate.eq("id", inventoryEntity.getId());
			inventoryDao.update(inventoryEntityUpdate, inventoryWrapperUpdate);
		}
		// 拣货记录更新
		UpdateWrapper<OrderdetaillistEntity> OrderdetaillistWrapperUpdate = new UpdateWrapper<OrderdetaillistEntity>();
		OrderdetaillistWrapperUpdate.eq("orderkey", orderdetaillistEntity.getOrderkey());
		OrderdetaillistWrapperUpdate.eq("line", orderdetaillistEntity.getLine());
		OrderdetaillistWrapperUpdate.eq("linelist", orderdetaillistEntity.getLinelist());
		OrderdetaillistWrapperUpdate.eq("id", orderdetaillistEntity.getId());
		OrderdetaillistWrapperUpdate.set("status", OrderConstant.ORDERSTATUS_21);
		orderdetaillistDao.update(null, OrderdetaillistWrapperUpdate);

		// 出库明细更新
		QueryWrapper<OrderdetailEntity> orderdetailQuery = new QueryWrapper<OrderdetailEntity>();
		orderdetailQuery.eq("orderkey", orderdetaillistEntity.getOrderkey());
		orderdetailQuery.eq("line", orderdetaillistEntity.getLine());
		OrderdetailEntity orderdetailEntity = baseDao.selectOne(orderdetailQuery);

		OrderdetailEntity orderdetailEntityUpdate = new OrderdetailEntity();
		// 设置实际出库量
		orderdetailEntityUpdate.setActqty(orderdetailEntity.getActqty().add(orderActqty));
		// 设置差异量，差异量的最小值为0
		if (orderActqty.compareTo(orderdetailEntity.getDiffqty()) > 0) {
			orderdetailEntityUpdate.setDiffqty(new BigDecimal(0));
		} else {
			orderdetailEntityUpdate.setDiffqty(orderdetailEntity.getDiffqty().subtract(orderActqty));
		}
		// 设置分配量 拣货明细的状态小于5的数量是分配量
		Integer status = orderdetaillistEntity.getStatus();
		if (status < OrderConstant.ORDERSTATUS_13) {
			if (orderActqty.compareTo(orderdetailEntity.getAllocateqty()) > 0) {
				orderdetailEntityUpdate.setAllocateqty(new BigDecimal(0));
			} else {
				orderdetailEntityUpdate.setAllocateqty(orderActqty.subtract(orderdetailEntity.getAllocateqty()));
			}
		} else if (status < OrderConstant.ORDERSTATUS_21) {
			// 设置拣货量
			if (orderActqty.compareTo(orderdetailEntity.getPickqty()) > 0) {
				orderdetailEntityUpdate.setPickqty(new BigDecimal(0));
			} else {
				orderdetailEntityUpdate.setPickqty(orderActqty.subtract(orderdetailEntity.getPickqty()));
			}
		}

		UpdateWrapper<OrderdetailEntity> orderdetailWrapperUpdate = new UpdateWrapper<OrderdetailEntity>();
		orderdetailWrapperUpdate.eq("orderkey", orderdetailEntity.getOrderkey());
		orderdetailWrapperUpdate.eq("line", orderdetailEntity.getLine());
		baseDao.update(orderdetailEntityUpdate, orderdetailWrapperUpdate);

		// 增加交易记录
		// 查询批次信息
		QueryWrapper<LotEntity> lotEntityQuery = new QueryWrapper<LotEntity>();
		lotEntityQuery.eq("lot", orderdetaillistEntity.getLot());
		LotEntity lotEntity = lotDao.selectOne(lotEntityQuery);

		String tradekey = sequenceService.getSequence("trade");
		TradeEntity tradeEntity = new TradeEntity();

		tradeEntity.setTradekey(tradekey);
		tradeEntity.setTradetype(TradeConstant.TRADETYPE_PICK);
		tradeEntity.setSku(orderdetaillistEntity.getSku());
		tradeEntity.setQty(orderActqty.negate());
		tradeEntity.setSourcetype(TradeConstant.SOURCETYPE_ORDERS);
		tradeEntity.setSourcekey(orderdetaillistEntity.getOrderkey());
		tradeEntity.setSourceline(orderdetaillistEntity.getLine());
		tradeEntity.setSourcelinelist(orderdetaillistEntity.getLinelist());
		tradeEntity.setFromlocation(orderdetaillistEntity.getLoc());
		tradeEntity.setTolocation("");
		tradeEntity.setFromtray(orderdetaillistEntity.getTray());
		tradeEntity.setTotray("");
		tradeEntity.setFrombox(orderdetaillistEntity.getBox());
		tradeEntity.setTobox("");
		tradeEntity.setFromlot(orderdetaillistEntity.getLot());
		tradeEntity.setTolot(null);
		tradeEntity.setFromlot1(null);
		tradeEntity.setFromlot2(null);
		tradeEntity.setFromlot3("");
		tradeEntity.setFromlot4("");
		tradeEntity.setFromlot5("");
		tradeEntity.setFromlot6("");
		tradeEntity.setFromlot7("");
		tradeEntity.setFromlot8("");
		tradeEntity.setFromlot9("");
		tradeEntity.setFromlot10("");
		tradeEntity.setFromlot11("");
		tradeEntity.setFromlot12("");
		tradeEntity.setFromlot13("");
		tradeEntity.setFromlot14("");
		tradeEntity.setFromlot15("");
		tradeEntity.setTolot1(lotEntity.getLot1());
		tradeEntity.setTolot2(lotEntity.getLot2());
		tradeEntity.setTolot3(lotEntity.getLot3());
		tradeEntity.setTolot4(lotEntity.getLot4());
		tradeEntity.setTolot5(lotEntity.getLot5());
		tradeEntity.setTolot6(lotEntity.getLot6());
		tradeEntity.setTolot7(lotEntity.getLot7());
		tradeEntity.setTolot8(lotEntity.getLot8());
		tradeEntity.setTolot9(lotEntity.getLot9());
		tradeEntity.setTolot10(lotEntity.getLot10());
		tradeEntity.setTolot11(lotEntity.getLot11());
		tradeEntity.setTolot12(lotEntity.getLot12());
		tradeEntity.setTolot13(lotEntity.getLot13());
		tradeEntity.setTolot14(lotEntity.getLot14());
		tradeEntity.setTolot15(lotEntity.getLot15());
		tradeDao.insert(tradeEntity);

		return null;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String release(List<OrderdetailEntity> orderList,String remoteAddr) {
		// 如果当前存在增在分配的订单，则不允许分配
		Integer countCurrnet = orderallocationDao.selectCount(null);
		if (countCurrnet > 0) {
			return MEGConstant.ORDER_HAS_OTHER_ALLOCATION;
		}

		for (OrderdetailEntity orderdetailEntity : orderList) {

			String msg = release(orderdetailEntity,remoteAddr);

			if (msg != null) {

				// 回滚事务
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return msg;

			}
		}

		return null;
	}

	private String release(OrderdetailEntity orderdetailEntity,String remoteAddr) {
		// 查找订单详细信息
		QueryWrapper<OrderdetailEntity> orderdetailQuery = new QueryWrapper<OrderdetailEntity>();
		orderdetailQuery.eq("orderkey", orderdetailEntity.getOrderkey());
		orderdetailQuery.eq("line", orderdetailEntity.getLine());
		orderdetailQuery.ne("status", OrderConstant.ORDERSTATUS_25);
		OrderdetailEntity orderdetail = baseDao.selectOne(orderdetailQuery);
		if (orderdetail == null) {
			return null;
		}
		BigDecimal allocateqty = orderdetail.getAllocateqty();
		if (allocateqty == null) {
			String msg = "请先分配再发放";
			return msg;
		} else {
			if (allocateqty.equals(BigDecimal.ZERO)) {
				String msg = "分配量为0，请先分配";
				return msg;
			}
		}

		// 查询未发放的分配明细
		QueryWrapper<OrderdetaillistEntity> orderdetaillistEntityQuery = new QueryWrapper<OrderdetaillistEntity>();
		orderdetaillistEntityQuery.eq("orderkey", orderdetail.getOrderkey());
		orderdetaillistEntityQuery.eq("line", orderdetail.getLine());
		orderdetaillistEntityQuery.le("status", OrderConstant.ORDERSTATUS_5);

		List<OrderdetaillistEntity> list = orderdetaillistDao.selectList(orderdetaillistEntityQuery);

		for (OrderdetaillistEntity orderdetaillistEntity : list) {
			// 添加拣货明细
			String msg = release(orderdetaillistEntity,remoteAddr);

		}

		orderdetaillistService.changeOrderStatus(orderdetailEntity.getOrderkey());
		return null;
	}

	private String release(OrderdetaillistEntity orderdetaillistEntity,String remoteAddr) {
		// 查询库位属性
		QueryWrapper<LocationEntity> queryLocation = new QueryWrapper<LocationEntity>();
		queryLocation.eq("location", orderdetaillistEntity.getLoc());
		LocationEntity locationEntity = locationDao.selectOne(queryLocation);
		String isCreate = locationEntity.getIscreate();
		if (StringUtils.isNotBlank(isCreate) && isCreate.equals("1")) {
			// 生成任务
			TaskEntity taskEntity = new TaskEntity();
			String taskkey = sequenceService.getSequence("task");

			taskEntity.setTaskkey(taskkey);
			taskEntity.setTasktype(TaskConstant.TASK_PICK);
			taskEntity.setPriority(0);
			taskEntity.setStatus(TaskConstant.TASK_0);
			taskEntity.setSourcekey(orderdetaillistEntity.getOrderkey());
			taskEntity.setSourceline(orderdetaillistEntity.getLine());
			taskEntity.setSourcelinelist(orderdetaillistEntity.getLinelist());
			taskEntity.setSku(orderdetaillistEntity.getSku());
			taskEntity.setQty(orderdetaillistEntity.getActqty());
			taskEntity.setFromlocation(orderdetaillistEntity.getLoc());
			taskEntity.setTolocation(orderdetaillistEntity.getToloc());
			taskEntity.setFromtray(orderdetaillistEntity.getTray());
			taskEntity.setTotray(orderdetaillistEntity.getTotray());
			taskEntity.setFrombox(orderdetaillistEntity.getBox());
			taskEntity.setTobox(orderdetaillistEntity.getTobox());
			taskEntity.setFromlot(orderdetaillistEntity.getLot());
			taskEntity.setTolot(orderdetaillistEntity.getLot());
			taskEntity.setRemark(orderdetaillistEntity.getRemark());
			taskEntity.setIp(remoteAddr);;
			taskDao.insert(taskEntity);

			// 更改拣货明细的状态
			UpdateWrapper<OrderdetaillistEntity> orderdetaillistUpdateStatus = new UpdateWrapper<OrderdetaillistEntity>();
			orderdetaillistUpdateStatus.eq("orderkey", orderdetaillistEntity.getOrderkey());
			orderdetaillistUpdateStatus.eq("line", orderdetaillistEntity.getLine());
			orderdetaillistUpdateStatus.eq("linelist", orderdetaillistEntity.getLinelist());
			orderdetaillistUpdateStatus.set("status", OrderConstant.ORDERSTATUS_9);
			orderdetaillistDao.update(null, orderdetaillistUpdateStatus);
		}
		return null;
	}

	@Override
	public String valide(OrderdetailDTO dto) {

		String orderkey = dto.getOrderkey();

		// 校验订单状态
		QueryWrapper<OrdersEntity> ordersQuery = new QueryWrapper<OrdersEntity>();
		ordersQuery.eq("orderkey", orderkey);
		OrdersEntity ordersEnity = ordersDao.selectOne(ordersQuery);
		Integer statusOrders = ordersEnity.getStatus();
		if (statusOrders == OrderConstant.ORDERSTATUS_25 || statusOrders == OrderConstant.ORDERSTATUS_30) {
			return "出库订单已关闭或已取消，无法新增明细";
		}

		// 校验商品
		QueryWrapper<SkuEntity> skuQuery = new QueryWrapper<SkuEntity>();
		skuQuery.eq("sku", dto.getSku());

		SkuEntity skuEntity = skuDao.selectOne(skuQuery);
		if (skuEntity == null) {
			return "物料信息不存在";
		}

		BigDecimal qty = dto.getQty();
		if (qty.compareTo(BigDecimal.ZERO) <= 0) {
			return "录入的数量必须为正数";
		}

		return null;
	}

	@Override
	public String valideDelete(Long[] ids) {
		QueryWrapper<OrderdetailEntity> query = new QueryWrapper<OrderdetailEntity>();
		query.in("id", ids);
		query.ne("status", OrderConstant.ORDERSTATUS_0);

		Integer count = baseDao.selectCount(query);

		if (count > 0) {
			return "不允许删除非新建的订单";
		}

		delete(ids);

		return null;

	}

}